package com.sc.admin.core.service.impl;


import cn.hutool.core.collection.CollectionUtil;
import com.sc.admin.core.dao.SysOrganizationMapper;
import com.sc.admin.core.dao.SysUserMapper;
import com.sc.admin.core.dao.SysUserOrganizationMapper;
import com.sc.admin.core.service.SysUserOrganizationService;
import com.sc.common.context.DefaultBusinessContext;
import com.sc.common.mapper.IBaseMapper;
import com.sc.common.dto.WebResponseDto;
import com.sc.common.entity.admin.organization.SysOrganization;
import com.sc.common.entity.admin.user.SysUser;
import com.sc.common.entity.admin.userorganization.SysUserOrganization;
import com.sc.common.enums.DataDictionaryEnum;
import com.sc.common.service.BaseServiceImpl;
import com.sc.common.util.MyIdUtil;
import org.apache.commons.collections.CollectionUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
import java.util.*;

/**
 * Created by wust on 2019/4/18.
 */
@Service("sysUserOrganizationServiceImpl")
public class SysUserOrganizationServiceImpl extends BaseServiceImpl<SysUserOrganization> implements SysUserOrganizationService {
    @Autowired
    private SysUserOrganizationMapper sysUserOrganizationMapper;

    @Autowired
    private SysUserMapper sysUserMapper;

    @Autowired
    private SysOrganizationMapper sysOrganizationMapper;

    @Override
    protected IBaseMapper getBaseMapper() {
        return sysUserOrganizationMapper;
    }

    @Transactional(rollbackFor=Exception.class)
    @Override
    public WebResponseDto create(Object obj) {
        WebResponseDto responseDto = new WebResponseDto();
        return responseDto;
    }

    @Transactional(rollbackFor=Exception.class)
    @Override
    public WebResponseDto update(Object obj) {
        WebResponseDto responseDto = new WebResponseDto();
        return responseDto;
    }

    @Transactional(rollbackFor=Exception.class)
    @Override
    public WebResponseDto delete(Object obj) {
        WebResponseDto responseDto = new WebResponseDto();
        return responseDto;
    }

    @Transactional(rollbackFor=Exception.class)
    @Override
    public void init() {
        DefaultBusinessContext ctx = DefaultBusinessContext.getContext();

        sysUserOrganizationMapper.deleteAll();

        SysUser sysUser = new SysUser();
        List<SysUser> sysUserList = sysUserMapper.select(sysUser);
        if(CollectionUtils.isNotEmpty(sysUserList)){
            for (SysUser user : sysUserList) {
                String type = user.getType();
                Long userId = user.getId();

                SysOrganization sysOrganizationSearch = new SysOrganization();
                sysOrganizationSearch.setRelationId(userId);
                sysOrganizationSearch.setType(DataDictionaryEnum.ORGANIZATION_TYPE_USER.getStringValue());
                List<SysOrganization> sysOrganizations =  sysOrganizationMapper.select(sysOrganizationSearch);
                if(CollectionUtils.isNotEmpty(sysOrganizations)) {
                    List<SysUserOrganization> sysUserOrganizations = new ArrayList<>(10);
                    if (DataDictionaryEnum.USER_TYPE_AGENT.getStringValue().equals(type)
                            || DataDictionaryEnum.USER_TYPE_PARENT_COMPANY.getStringValue().equals(type)
                            || DataDictionaryEnum.USER_TYPE_BRANCH_COMPANY.getStringValue().equals(type)
                            || DataDictionaryEnum.USER_TYPE_PROJECT.getStringValue().equals(type)) { // 运营管理员
                        SysOrganization sysOrganization = sysOrganizations.get(0); // 同一个代理商、总公司、分公司、项目账号只能在组织架构出现一次，因此取集合第一个即可
                        SysUserOrganization sysUserOrganization = new SysUserOrganization();
                        sysUserOrganization.setId(MyIdUtil.getId());
                        sysUserOrganization.setUserId(userId);
                        sysUserOrganization.setCreaterId(ctx.getAccountId());
                        sysUserOrganization.setCreaterName(ctx.getAccountName());
                        sysUserOrganization.setCreateTime(new Date());
                        sysUserOrganization.setIsDeleted(0);
                        sysUserOrganizations.add(sysUserOrganization);
                        lookupByBusinessAdmin(sysOrganization.getPid(),sysUserOrganization,sysUserOrganizations);
                    } else if (DataDictionaryEnum.USER_TYPE_BUSINESS.getStringValue().equals(type)) { // 业务操作员
                        for (SysOrganization sysOrganization : sysOrganizations) {
                            SysUserOrganization sysUserOrganization = new SysUserOrganization();
                            sysUserOrganization.setId(MyIdUtil.getId());
                            sysUserOrganization.setUserId(userId);
                            sysUserOrganization.setCreaterId(ctx.getAccountId());
                            sysUserOrganization.setCreaterName(ctx.getAccountName());
                            sysUserOrganization.setCreateTime(new Date());
                            sysUserOrganization.setIsDeleted(0);
                            sysUserOrganizations.add(sysUserOrganization);
                            lookupByBusinessUser(sysOrganization.getPid(),sysUserOrganization,sysUserOrganizations);
                        }
                    }
                    if(CollectionUtil.isNotEmpty(sysUserOrganizations)){
                        sysUserOrganizationMapper.insertList(sysUserOrganizations);
                    }
                }
            }
        }
    }


    @Override
    public void initByUser(Long userId) {
        DefaultBusinessContext ctx = DefaultBusinessContext.getContext();

        SysUserOrganization userOrganizationSearch = new SysUserOrganization();
        userOrganizationSearch.setUserId(userId);
        sysUserOrganizationMapper.delete(userOrganizationSearch);

        SysUser user = sysUserMapper.selectByPrimaryKey(userId);
        if(user == null){
            return;
        }

        String type = user.getType();

        SysOrganization sysOrganizationSearch = new SysOrganization();
        sysOrganizationSearch.setRelationId(userId);
        sysOrganizationSearch.setType(DataDictionaryEnum.ORGANIZATION_TYPE_USER.getStringValue());
        List<SysOrganization> sysOrganizations =  sysOrganizationMapper.select(sysOrganizationSearch);
        if(CollectionUtils.isNotEmpty(sysOrganizations)) {
            List<SysUserOrganization> sysUserOrganizations = new ArrayList<>(10);
            if (DataDictionaryEnum.USER_TYPE_AGENT.getStringValue().equals(type)
                    || DataDictionaryEnum.USER_TYPE_PARENT_COMPANY.getStringValue().equals(type)
                    || DataDictionaryEnum.USER_TYPE_BRANCH_COMPANY.getStringValue().equals(type)
                    || DataDictionaryEnum.USER_TYPE_PROJECT.getStringValue().equals(type)) { // 运营管理员
                SysOrganization sysOrganization = sysOrganizations.get(0); // 同一个代理商、总公司、分公司、项目账号只能在组织架构出现一次，因此取集合第一个即可
                SysUserOrganization sysUserOrganization = new SysUserOrganization();
                sysUserOrganization.setId(MyIdUtil.getId());
                sysUserOrganization.setUserId(userId);
                sysUserOrganization.setCreaterId(ctx.getAccountId());
                sysUserOrganization.setCreaterName(ctx.getAccountName());
                sysUserOrganization.setCreateTime(new Date());
                sysUserOrganization.setIsDeleted(0);
                sysUserOrganizations.add(sysUserOrganization);
                lookupByBusinessAdmin(sysOrganization.getPid(),sysUserOrganization,sysUserOrganizations);
            } else if (DataDictionaryEnum.USER_TYPE_BUSINESS.getStringValue().equals(type)) { // 业务操作员
                for (SysOrganization sysOrganization : sysOrganizations) {
                    SysUserOrganization sysUserOrganization = new SysUserOrganization();
                    sysUserOrganization.setId(MyIdUtil.getId());
                    sysUserOrganization.setUserId(userId);
                    sysUserOrganization.setCreaterId(ctx.getAccountId());
                    sysUserOrganization.setCreaterName(ctx.getAccountName());
                    sysUserOrganization.setCreateTime(new Date());
                    sysUserOrganization.setIsDeleted(0);
                    sysUserOrganizations.add(sysUserOrganization);
                    lookupByBusinessUser(sysOrganization.getPid(),sysUserOrganization,sysUserOrganizations);
                }
            }
            if(CollectionUtil.isNotEmpty(sysUserOrganizations)){
                sysUserOrganizationMapper.insertList(sysUserOrganizations);
            }
        }
    }

    /**
     *  运营方账号有三种：代理商的账号、总公司的账号、分公司的账号。分三种情况搜寻：
     *  1.代理商账号搜寻方式：先向上递归搜寻到代理商，再向下递归搜寻到分公司(搜寻路径：账号->角色->部门->代理商)；
     *  2.总公司账号搜寻方式：先向上递归搜寻到代理商，再向下递归搜寻到分公司(搜寻路径：账号->角色->部门->总公司->代理商)；
     *  3.分公司账号搜寻方式：直接向上递归搜寻到代理商(搜寻路径：账号->角色->部门->分公司->总公司->代理商)；
     *  4.项目司账号搜寻方式：直接向上递归搜寻到代理商(搜寻路径：账号->角色->部门->项目->项目部->分公司->总公司->代理商)。
     *
     *  递归到顶层即代理层后，需要分情况判断是否需要向下递归扎到总公司或者分公司。1路径需要向下递归找到总公司和分公司，2需要向下递归找到分公司。
     * @param organizationId
     * @param sysUserOrganization
     */
    private void lookupByBusinessAdmin(Long organizationId,final SysUserOrganization sysUserOrganization,final List<SysUserOrganization> sysUserOrganizations){
        SysOrganization sysOrganizationSearch = new SysOrganization();
        sysOrganizationSearch.setId(organizationId);
        SysOrganization sysOrganization = sysOrganizationMapper.selectOne(sysOrganizationSearch);
        if(sysOrganization != null){
            if(DataDictionaryEnum.ORGANIZATION_TYPE_ROLE.getStringValue().equals(sysOrganization.getType())){
                sysUserOrganization.setRoleId(sysOrganization.getRelationId());
                lookupByBusinessAdmin(sysOrganization.getPid(),sysUserOrganization,sysUserOrganizations);
            }else if(DataDictionaryEnum.ORGANIZATION_TYPE_DEPARTMENT.getStringValue().equals(sysOrganization.getType())){
                sysUserOrganization.setDepartmentId(sysOrganization.getRelationId());
                lookupByBusinessAdmin(sysOrganization.getPid(),sysUserOrganization,sysUserOrganizations);
            }else if(DataDictionaryEnum.ORGANIZATION_TYPE_PROJECT.getStringValue().equals(sysOrganization.getType())){
                sysUserOrganization.setProjectId(sysOrganization.getRelationId());
                lookupByBusinessAdmin(sysOrganization.getPid(),sysUserOrganization,sysUserOrganizations);
            }else if(DataDictionaryEnum.ORGANIZATION_TYPE_BRANCH_COMPANY.getStringValue().equals(sysOrganization.getType())){
                sysUserOrganization.setBranchCompanyId(sysOrganization.getRelationId());
                lookupByBusinessAdmin(sysOrganization.getPid(),sysUserOrganization,sysUserOrganizations);
            }else if(DataDictionaryEnum.ORGANIZATION_TYPE_PARENT_COMPANY.getStringValue().equals(sysOrganization.getType())){
                sysUserOrganization.setParentCompanyId(sysOrganization.getRelationId());
                lookupByBusinessAdmin(sysOrganization.getPid(),sysUserOrganization,sysUserOrganizations);
            }else if(DataDictionaryEnum.ORGANIZATION_TYPE_AGENT.getStringValue().equals(sysOrganization.getType())){
                sysUserOrganization.setAgentId(sysOrganization.getRelationId());
            }
        }
    }


    /**
     *  业务操作方账号搜寻路径：账号->角色->部门->项目->分公司->总公司->代理商
     *
     * @param organizationId
     * @param sysUserOrganization
     */
    private void lookupByBusinessUser(Long organizationId,final SysUserOrganization sysUserOrganization,final List<SysUserOrganization> sysUserOrganizations){
        SysOrganization sysOrganizationSearch = new SysOrganization();
        sysOrganizationSearch.setId(organizationId);
        SysOrganization sysOrganization = sysOrganizationMapper.selectOne(sysOrganizationSearch);
        if(sysOrganization != null){
            if(DataDictionaryEnum.ORGANIZATION_TYPE_ROLE.getStringValue().equals(sysOrganization.getType())){
                sysUserOrganization.setRoleId(sysOrganization.getRelationId());
                lookupByBusinessUser(sysOrganization.getPid(),sysUserOrganization,sysUserOrganizations);
            }else if(DataDictionaryEnum.ORGANIZATION_TYPE_DEPARTMENT.getStringValue().equals(sysOrganization.getType())){
                sysUserOrganization.setDepartmentId(sysOrganization.getRelationId());
                lookupByBusinessUser(sysOrganization.getPid(),sysUserOrganization,sysUserOrganizations);
            }else if(DataDictionaryEnum.ORGANIZATION_TYPE_PROJECT.getStringValue().equals(sysOrganization.getType())){
                sysUserOrganization.setProjectId(sysOrganization.getRelationId());
                lookupByBusinessUser(sysOrganization.getPid(),sysUserOrganization,sysUserOrganizations);
            }else if(DataDictionaryEnum.ORGANIZATION_TYPE_BRANCH_COMPANY.getStringValue().equals(sysOrganization.getType())){
                sysUserOrganization.setBranchCompanyId(sysOrganization.getRelationId());
                lookupByBusinessUser(sysOrganization.getPid(),sysUserOrganization,sysUserOrganizations);
            }else if(DataDictionaryEnum.ORGANIZATION_TYPE_PARENT_COMPANY.getStringValue().equals(sysOrganization.getType())){
                sysUserOrganization.setParentCompanyId(sysOrganization.getRelationId());
                lookupByBusinessUser(sysOrganization.getPid(),sysUserOrganization,sysUserOrganizations);
            }else if(DataDictionaryEnum.ORGANIZATION_TYPE_AGENT.getStringValue().equals(sysOrganization.getType())){
                sysUserOrganization.setAgentId(sysOrganization.getRelationId());
            }
        }
    }
}
